package com.ssl.rms.util;

import com.google.common.collect.Lists;
import com.ssl.rms.component.SpringContextHolder;
import com.ssl.rms.entity.Menu;
import com.ssl.rms.service.MenuService;
import com.ssl.rms.utils.JsonMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/**
 * 描述：菜单树形工具
 *
 * @author ssl
 * @create 2018/03/29 15:59
 */
public class MenuTreeUtils {
    private static Logger logger = LoggerFactory.getLogger(MenuTreeUtils.class);

    /**
     * 将菜单集合按照树形结构返回
     *
     * @param menus
     * @return json 字符串
     */
    public static String getTreeMenuJson(List<Menu> menus) {
        return JsonMapper.toJsonString(getTreeMenu(menus));
    }

    /**
     * 将菜单集合按照树形结构返回
     *
     * @param menus
     * @return list
     */
    public static List<Menu> getTreeMenu(List<Menu> menus) {
        /** 结构化之后的树 */
        List<Menu> menuList = Lists.newArrayList();
        /** 循环需要查询的菜单列表，找到所有的一级菜单 */
        for (Menu menu : menus) {
            /** 父级菜单id为null，代表该菜单为一级菜单 */
            if (null == menu.getParentId()) {
                menuList.add(menu);
            }
        }
        /** 排序 */
        sortListAsc(menuList);
        /** 给一级菜单设置子菜单 */
        for (Menu menu : menuList) {
            menu.setChildMenu(getMenuChild(menu.getId(), menus));
        }
        return menuList;
    }

    /**
     * 递归查询子菜单
     *
     * @param id        当前菜单id
     * @param rootMenus 要查找的列表
     * @return
     */
    private static List<Menu> getMenuChild(Long id, List<Menu> rootMenus) {
        List<Menu> childList = Lists.newArrayList();
        for (Menu menu : rootMenus) {
            /** 遍历所有节点，将父菜单id与传过来的id比较 */
            if (null != menu.getParentId() && id.equals(menu.getParentId())) {
                childList.add(menu);
            }
        }
        /** 如果子菜单没有了，则返回null */
        if (0 == childList.size()) {
            return null;
        }
        /** 排序 */
        sortListAsc(childList);
        /** 循环子菜单的子菜单 */
        for (Menu menu : childList) {
            /** 递归获取子菜单 */
            menu.setChildMenu(getMenuChild(menu.getId(), rootMenus));
        }
        return childList;
    }

    /**
     * 按照sort属性进行降序排列:值大的排在前面
     *
     * @param menuList
     */
    private static void sortListDesc(List<Menu> menuList) {
        Collections.sort(menuList, (o1, o2) -> {
            /** 按照sort字段进行降序排列 */
            if (o1.getSort() > o2.getSort()) {
                return -1;
            }
            if (Objects.equals(o1.getSort(), o2.getSort())) {
                return 0;
            }
            return 1;
        });
    }

    /**
     * 按照sort属性进行升序排列：值小的排在前面
     *
     * @param menuList
     */
    private static void sortListAsc(List<Menu> menuList) {
        Collections.sort(menuList, (o1, o2) -> {
            if (o1.getSort() < o2.getSort()) {
                return -1;
            }
            if (Objects.equals(o1.getSort(), o2.getSort())) {
                return 0;
            }
            return 1;
        });
    }
}
